package eRepublik;

import main.*;
import java.net.URLEncoder;
import java.sql.*;
import java.util.*;
import org.jibble.pircbot.PircBot;
import org.json.JSONObject;

public class Citizen extends PircBot {
	
	//Errors, again
	String[] error ={	"4Error: Only bot administrators can use this command!", 
						"4Error: Only channel operators or above can use this command!", 
						"4Error: There is a fault within the API. Please try again soon.",
						"4Error: Citizen does not exist.",
						"4Error: Only channel owners can use this command!.",
						"4MySQL Error: Please join #eRepBot for help.",
						"4Error: Citizen cannot be resolved. Please try again or try using the Citizen's ID."
					};
					
	//For using the erpk API system
	String apikey = "IshVQwOx";
	
	//Other classes
	general general = new general();
	
	//Method to use the erpk API to return citizens ID based on name
	public String citizenSearch(String name) {
		String id = "";
		try {
			//Encode the url correctly for spaces and such
			String request = "http://gamingtools.co.uk/id.php?name=" + URLEncoder.encode(name, "ISO-8859-1");
			
			//Now, get the jsonString and check there is actually data (or else theres no citizen)
			String jsonString = general.readUrl(request);
			
			//Convert the string to a JSON Object
			JSONObject json = new JSONObject(jsonString);
			//Now simply get the ID..
			id = json.getString("id");
			if (id.equals("")) {
				id = error[3];
			}
		} catch (Exception e) {
			e.printStackTrace();
			id = error[2];
		}
		return id;
	}
	private Map<String,String> getCitData(String resource, String action,Map<String,String> query) {

		Map<String, String> citizen = new HashMap<String,String>();
		try {
			String jsonString = general.getJSON(resource, action, query);
			//Get JSON data from API
			JSONObject json = new JSONObject(jsonString);
			JSONObject cit = json.getJSONObject("message");
			
			JSONObject gen = cit.getJSONObject("general");
			JSONObject military = cit.getJSONObject("militaryAttributes");
			JSONObject location = cit.getJSONObject("location");
			
			//Assign the information to variables. Some might be Double or Int, therefore must convert to string to send to IRC
			citizen.put("name",gen.getString("name"));
			citizen.put("strength",Double.toString(military.getDouble("strength")));
			citizen.put("level",Integer.toString(gen.getInt("level")));
			citizen.put("experience",Integer.toString(gen.getInt("experience_points")));
			citizen.put("birth",gen.getString("birthDay"));	
			citizen.put("rank_points", Integer.toString(military.getInt("rank_points")));
			citizen.put("country",location.getString("residence_country_name"));
			citizen.put("region",location.getString("residence_region_name"));
			citizen.put("citizenship",location.getString("citizenship_country_name"));
			
			String rank_name = military.getString("rank_name");
			int stars = military.getInt("rank_stars");
			
			for (int i=0; i < stars; i++) {
				rank_name = rank_name + "*";
			}
			citizen.put("rank_name",rank_name);
			
			Connection con = general.getmySQLConnection();
			try {
				//Create a new statement to use
				Statement state = con.createStatement();
				//Create a ResultsSet object to take results from
				ResultSet results = state.executeQuery("SELECT * FROM milranks WHERE name = '" + rank_name + "'");
				//while there is another line
				while (results.next() == true) {
					citizen.put("rank_level",results.getString(1));
				}
				con.close();
			} catch (Exception e) {
				//Print the Exception
					System.out.println("Exception: " + e.getMessage());
			}
			
			//Just to start off division check, gotta do it as int :P
			int levelCheck = gen.getInt("level");
			//Find division
			if (levelCheck <= 24) {
				citizen.put("division","1");
			} else if (levelCheck > 24 && levelCheck <= 29) {
				citizen.put("division","2");
			} else if (levelCheck > 29 && levelCheck <= 36 ) {
				citizen.put("division","3");
			} else if (levelCheck > 36) {
				citizen.put("division","4");
			}
		} catch (Exception e) {
			e.printStackTrace();
			citizen.put("error","error");
			return citizen;
		}

		return citizen;
	}
	
	public String citizenLookup(String id) {
		
		Map<String, String> query = new HashMap<String,String>();
		query.put("citizenid",id);
		
		Map<String,String> citizen = getCitData("citizen","profile",query);
				
		//Formatting information for sending to IRC
		String send =  citizen.get("name")+" ["+id+"] 3|| 2Strength: "+citizen.get("strength")
				+ " 3|| 2Level: "+citizen.get("level") + " ["+citizen.get("experience")+"]"
				+ " 3|| 2Birth: "+citizen.get("birth")+" 3|| 2Division: "+citizen.get("division")
				+ " 3|| 2Rank: "+citizen.get("rank_name")+ " 3|| 2Rank Points: "+citizen.get("rank_points")
				+" 3|| 2Location: "+citizen.get("region")+ ", "+citizen.get("country")
				+" 3|| 2Citizenship: " + citizen.get("citizenship");
		
		return send;
	}
	
	public String fightCalc(String id, int fights, int rank, double str) {
		
		// Get citizen data and start MySQL Conn
		Map<String, String> query = new HashMap<String,String>();
		query.put("citizenid",id);
		
		Map<String,String> citizen = getCitData("citizen","profile",query);
		Connection con = general.getmySQLConnection();
		
		// Get influence and initialise variables
		int[] influence = influence(citizen, fights, rank, str);
		String inf = "";
		String rank_name = "";
		for (int i=0; i < influence.length; i++){
			inf = inf+" 3|| 2Q"+i+": "+influence[i];
		}
		
		try {
			//Create a new statement to use
			Statement state = con.createStatement();
			//Create a ResultsSet object to take results from
			ResultSet results = state.executeQuery("SELECT * FROM milranks WHERE level = " + rank);
			//while there is another line
			while (results.next() == true) {
				rank_name  = results.getString(2);
			}
			con.close();
		} catch (Exception e) {
			//Print the Exception
				System.out.println("Exception: " + e.getMessage());
		}
		
		//If rank/str tags are empty
		if (rank == 0) {
			rank = Integer.parseInt(citizen.get("rank_level"));
			rank_name = citizen.get("rank_name");
		}
		if (str == 0) {
			str = Double.parseDouble(citizen.get("strength"));
		}
		
		String send =  citizen.get("name")+" ["+id+"] 3|| 2Strength: "+str
				+ " 3|| 2Rank: "+rank_name+ " ["+rank+"]"
				+ " 3|| 2Fights: "+fights + inf;
		
		return send;
	}
	
	public String dmgCalc(String id, int rank) {
		
		
		Map<String, String> query = new HashMap<String,String>();
		query.put("citizenid",id);
		
		Map<String,String> citizen = getCitData("citizen","profile",query);
		
		Connection con = general.getmySQLConnection();
		
		int rank_points = 0;
		String rank_name = "";
		
		if (rank == 0) {
			rank = Integer.parseInt(citizen.get("rank_level"));
		} else {
			rank = rank - 1;
		}
		try {
			//Create a new statement to use
			Statement state = con.createStatement();
			//Create a ResultsSet object to take results from
			ResultSet results = state.executeQuery("SELECT * FROM milranks WHERE level = " + rank);
			//while there is another line
			while (results.next() == true) {
				rank_points  = Integer.parseInt(results.getString(3));
			}
			
			ResultSet results2 = state.executeQuery("SELECT * FROM milranks WHERE level = " + (rank+1));
			//while there is another line
			while (results2.next() == true) {
				rank_name = results2.getString(2);
			}
			con.close();
		} catch (Exception e) {
			//Print the Exception
				System.out.println("Exception: " + e.getMessage());
		}
		
		double pointsLeft = rank_points - Integer.parseInt(citizen.get("rank_points"));
		int dmg = (int) pointsLeft * 10;
		
		String send =  citizen.get("name")+" ["+id+"] 3|| 2Strength: "+citizen.get("strength")
				+ " 3|| 2Rank: "+citizen.get("rank_name")+ " ["+citizen.get("rank_level")+"] 3|| 2Damage until 7"+ rank_name +"2: " + dmg;
		
		return send;
	}
	
	public String fightsLeft(String id) {
		
		Map<String, String> query = new HashMap<String,String>();
		query.put("citizenid",id);
		
		Map<String,String> citizen = getCitData("citizen","profile",query);
		
		int[] influence = influence(citizen, 1, 0, 0);
		String fights = fights(citizen, influence);
		
		String send =  citizen.get("name")+" ["+id+"] 3|| 2Rank: "+citizen.get("rank_name")
				+ " ["+citizen.get("rank_level")+"]" + fights;
		
		return send;
	}
	
	public String fights(Map<String,String> citizen, int[] influence) {
		
		Connection con = general.getmySQLConnection();
		
		int rank_points = 0;
		
		try {
			//Create a new statement to use
			Statement state = con.createStatement();
			//Create a ResultsSet object to take results from
			ResultSet results = state.executeQuery("SELECT * FROM milranks WHERE level = " + citizen.get("rank_level"));
			//while there is another line
			while (results.next() == true) {
				rank_points = Integer.parseInt(results.getString(3));
			}
			con.close();
		} catch (Exception e) {
			//Print the Exception
				System.out.println("Exception: " + e.getMessage());
		}
		
		double pointsLeft = rank_points - Integer.parseInt(citizen.get("rank_points"));
		
		int i =0;
		String fights = "";
		for (int inf : influence) {
			double f = Math.ceil((pointsLeft / inf) * 10);
			fights = fights + " 3|| 2Q"+i+": "+ (int) f;
			i++;
		}
		
		return fights;
	}
	
	public int[] influence(Map<String,String> citizen, int fights, int rank, double str) {
		int[] inf = new int[8];
		
		// Weapon qualities
		double[] q = {0,20,40,60,80,100,120,200};
		
		// No STR tag
		if (str == 0.0) {
			str = Double.parseDouble(citizen.get("strength"));
		}
		
		// Loop through each inf (would work with Q too)
		for (int i=0; i < inf.length; i++){
			double level = Double.parseDouble(citizen.get("rank_level"));
			if (rank != 0) {
				level = rank;
			}
			double influence = ((level-1)/20 + 0.3) * (((str/10)+40)*(1 + (q[i]/100)));
			influence = influence * fights;
			inf[i] = (int) influence;
		}
		
		return inf;
	}
}